﻿#ifndef __SS_STRFUNC_H__
#define __SS_STRFUNC_H__
#include "../ssBaseDefine.h"
#include <cstdio>
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#include <string>
#include <sstream>
#include <vector>

#ifdef SS_USE_WINDOWS
//#define snprintf _snprintf//最新的VC已自带此函数定义
#define snwprintf _snwprintf
#define vsnwprintf _vsnwprintf
#define strxcopy(des,des_len,src) strcpy_s(des,des_len,src)
#define strcasecmp stricmp
#define strncasecmp strnicmp
#else
#define snwprintf swprintf
#define vsnwprintf vswprintf
#define vsnwprintf vswprintf
#define strxcopy(des,des_len,src) strlcpy(des,src,des_len)
#endif


namespace StarSeeker
{

template<typename T>
u32 StrLen(const T* s)
{
	for (u32 i = 0; i < SS_1GB; ++i)
	{
		if (s[i] == 0)
		{
			return i;
		}
	}
	return 0;
}

template<typename T>
u32 StrCpy(T* buf, u32 buflen, const T* src, u32 srclen)
{
	u32 cpylen = buflen > srclen ? srclen : (buflen - 1);
	memcpy(buf, src, cpylen*sizeof(T));
	buf[cpylen] = 0;
	return cpylen;
}
template<typename T>
u32 StrCpy(T* buf, u32 buflen, const T* src)
{
	u32 len = StrLen<T>(src);
	return StrCpy<T>(buf, buflen, src, len);
}

inline std::string Int32ToStr(int a)
{
	char num[16] = { 0 };
	snprintf(num, 16, "%d", a);
	num[15] = 0;
	return num;
}

inline std::wstring Int32ToWStr(int a)
{
	wchar_t num[16] = { 0 };
	snwprintf(num, 16, L"%d", a);
	num[15] = 0;
	return num;
}

inline std::string Int64ToStr(long long a)
{
	char num[24] = { 0 };
	snprintf(num, 24, "%lld", a);
	num[23] = 0;
	return num;
}

inline std::wstring Int64ToWStr(long long a)
{
	wchar_t num[24] = { 0 };
	snwprintf(num, 24, L"%lld", a);
	num[23] = 0;
	return num;
}

inline std::string floatToStr(float a)
{
	char num[32] = { 0 };
	snprintf(num, 32, "%f", a);
	num[31] = 0;
	return num;
}

inline std::wstring floatToWStr(float a)
{
	wchar_t num[32] = { 0 };
	snwprintf(num, 32, L"%f", a);
	num[31] = 0;
	return num;
}

template<typename T>
inline std::string Num2Str(T t)
{
	std::ostringstream o;
	if (o << t)
		return o.str();
	return "";
}
template<typename T>
inline void Num2Str(T t, char* buf, u32 len)
{
	std::ostringstream o;
	if (o << t)
	{
		std::string& str = o.str();
		StrCpy<char>(buf, len, str.c_str(), str.size());
	}
}

template<typename T>
inline std::wstring Num2WStr(T t)
{
	std::wostringstream o;
	if (o << t)
		return o.str();
	return L"";
}
template<typename T>
inline void Num2WStr(T t, wchar_t* buf, u32 len)
{
	std::wostringstream o;
	if (o << t)
	{
		std::wstring& str = o.str();
		StrCpy<wchar_t>(buf, len, str.c_str(), str.size());
	}
}

inline int Str2Int32(const char* str)
{
	return ::atoi(str);
}

inline int WStr2Int32(const wchar_t* str)
{
	int a = 0;
	swscanf(str, L"%d", &a);
	return a;
}

inline unsigned int Str2UInt32(const char* str)
{
	unsigned int a = 0;
	sscanf(str, "%u", &a);
	return a;
}

inline unsigned int WStr2UInt32(const wchar_t* str)
{
	unsigned int a = 0;
	swscanf(str, L"%u", &a);
	return a;
}

inline long long Str2Int64(const char* str)
{
	return ::atoll(str);
}

inline unsigned long long Str2UInt64(const char* str)
{
	unsigned long long a = 0;
	sscanf(str, "%llu", &a);
	return a;
}

inline long long WStr2Int64(const wchar_t* str)
{
	long long a = 0;
	swscanf(str, L"%lld", &a);
	return a;
}

inline unsigned long long WStr2UInt64(const wchar_t* str)
{
	unsigned long long a = 0;
	swscanf(str, L"%llu", &a);
	return a;
}

inline float Str2Float(const char* str)
{
	return (float)::atof(str);
}

inline float WStr2Float(const wchar_t* str)
{
	float a = 0.0f;
	swscanf(str, L"%f", &a);
	return a;
}

template<typename T>
inline T Str2Num(const char* s)
{
	std::istringstream i(s);
	T x;
	if (i >> x)
		return x;
	return 0;
}

template<typename T>
inline T WStr2Num(const wchar_t* s)
{
	std::wistringstream i(s);
	T x;
	if (i >> x)
		return x;
	return 0;
}

//按分隔符拆分字符串
inline void StringSplit(std::string& str, char flag, std::vector<std::string>& list)
{
	if (str.size() > 1)
	{
		list.clear();
		std::string tmpStr;
		u32 begin = 0;
		for (u32 i = 0; i <= str.size(); ++i)
		{
			if (str[i] == flag || str[i] == 0)
			{
				tmpStr.clear();
				tmpStr = str.substr(begin, i - begin);
				if (tmpStr.size() > 0)
				{
					list.push_back(tmpStr);
				}
				begin = i + 1;
			}
		}
	}
}

}

#endif
